#pragma once

#include <memory>

#include "planner/operator.h"
#include "planner/operator_visitor.h"

namespace optimizer {

struct ExprRewriter {
  bool Match(Expr *expr, Expr *pattern);

  Expr *RewriteAndReplace(Expr *expr, Expr *pattern, Expr *replacement);
};

class Normalizer : public OperatorVisitor {
 public:
  explicit Normalizer(std::shared_ptr<Operator> op_tree);

  std::shared_ptr<Operator> Normalize();

  void Visit(LogicalGet *logical_get) override;

 private:
  std::shared_ptr<Operator> parent_;

  List *ExprRewriter(List *expr);
};

}  // namespace optimizer